package com.richard.library.basic.basic;

import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.annotation.IdRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;

import com.richard.library.basic.R;
import com.richard.library.basic.basic.uiview.UIView;
import com.richard.library.basic.basic.uiview.UIViewImpl;
import com.richard.library.basic.eventbus.EventData;
import com.richard.library.basic.util.FragmentUtil;
import com.richard.library.basic.widget.NavigationBar;
import com.richard.library.basic.widget.PlaceHolderView;
import com.richard.library.context.AppContext;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.List;

/**
 * <pre>
 * Description : Fragment基类
 * Author : admin-richard
 * Date : 2019-05-10 17:57
 * Changelog:
 * Version            Date            Author              Detail
 * ----------------------------------------------------------------------
 * 1.0         2019-05-10 17:57      admin-richard         new file.
 * </pre>
 */
public abstract class BasicFragment extends Fragment implements UIInitializer {

    private UIView mUIView;
    protected NavigationBar navigationbar;
    //布局根视图
    private LinearLayout rootView;
    //布局文件ID
    private int layoutId;
    //布局内容视图
    private View contentView;

    private PlaceHolderView mPlaceHolderView;


    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        if (rootView != null) {
            return rootView;
        }

        this.initLayoutView();

        if (contentView == null) {
            contentView = inflater.inflate(layoutId, null);
        }

        rootView = new LinearLayout(getContext());
        rootView.setLayoutParams(new ViewGroup.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT
                , ViewGroup.LayoutParams.MATCH_PARENT
        ));
        rootView.setId(R.id.basic_content_root);
        rootView.setOrientation(LinearLayout.VERTICAL);

        navigationbar = new NavigationBar(getContext());
        navigationbar.setVisibility(View.GONE);
        rootView.addView(navigationbar, new LinearLayout.LayoutParams(
                ViewGroup.LayoutParams.MATCH_PARENT
                , AppContext.getDimensionPixelSize(R.dimen.navigation_bar_height)
        ));

        //更新子View大小
        if (contentView != null) {
            ViewGroup.LayoutParams childLayoutParams = contentView.getLayoutParams();
            if (childLayoutParams == null) {
                rootView.addView(contentView, new ViewGroup.LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT
                        , ViewGroup.LayoutParams.MATCH_PARENT
                ));
            } else {
                childLayoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
                childLayoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT;
                rootView.addView(contentView);
            }
        }

        return rootView;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        this.initNavigation();
        mUIView = new UIViewImpl(this.getContext());

        if (!EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().register(this);
        }

        this.initData();
        this.bindListener();
    }

    @Override
    public void onResume() {
        super.onResume();
        this.onUserVisible(isUserVisible());
    }

    @Override
    public void onPause() {
        super.onPause();
        this.onUserVisible(isUserVisible());
    }

    @Override
    public void onHiddenChanged(boolean hidden) {
        super.onHiddenChanged(hidden);
        this.onUserVisible(isUserVisible());
        this.handleUserVisible();
    }

    @Override
    public void onDestroy() {
        if (EventBus.getDefault().isRegistered(this)) {
            EventBus.getDefault().unregister(this);
        }
        if (mUIView != null) {
            mUIView.dismissLoading();
            mUIView.dismissMsgDialog();
            mUIView = null;
        }
        navigationbar = null;
        rootView = null;
        contentView = null;
        mPlaceHolderView = null;
        super.onDestroy();
    }

    /**
     * 处理对用户的可见性
     */
    void handleUserVisible() {
        List<Fragment> fragment = FragmentUtil.getFragments(getChildFragmentManager());
        for (Fragment item : fragment) {
            if (item instanceof BasicFragment) {
                BasicFragment f = ((BasicFragment) item);
                f.onUserVisible(isUserVisible());
                f.handleUserVisible();
            } else if (item instanceof BasicDialogFragment) {
                BasicDialogFragment f = ((BasicDialogFragment) item);
                f.onUserVisible(isUserVisible());
                f.handleUserVisible();
            }
        }
    }

    /**
     * 当前fragment对用户是否可见
     */
    public boolean isUserVisible() {
        if (!isResumed()) {
            return false;
        }

        Fragment fragment = getParentFragment();
        if (fragment == null) {
            return !isHidden();
        }

        while (true) {
            Fragment f = fragment.getParentFragment();
            if (f == null) {
                return !fragment.isHidden();
            }
            fragment = f;
        }
    }

    /**
     * 初始化导航条
     */
    private void initNavigation() {
        if (navigationbar == null) {
            return;
        }
        navigationbar.openTranslucentStatusBar(getActivity());//开启沉侵式状态栏
        navigationbar.setRightImageView(R.mipmap.icon_close);
        navigationbar.setRightImageViewShow(true);
        navigationbar.setRightImageViewClickListener((v) -> finish());
    }

    /**
     * 设置视图内容占位目标view
     */
    protected void setPlaceHolderTarget(View targetView) {
        if (mPlaceHolderView != null) {
            return;
        }
        mPlaceHolderView = new PlaceHolderView(getContext(), targetView);
    }


    /**
     * 获取内容占位图
     */
    protected PlaceHolderView getPlaceHolderView() {
        //默认contentView为操纵View
        if (mPlaceHolderView == null) {
            this.setPlaceHolderTarget(findViewById(R.id.basic_content_root));
        }
        return mPlaceHolderView;
    }

    protected void setContentView(View contentView) {
        this.contentView = contentView;
    }

    protected void setContentView(@LayoutRes int layoutId) {
        this.layoutId = layoutId;
    }

    public void finish() {
        FragmentActivity activity = getActivity();
        if (activity != null) {
            activity.finish();
        }
    }

    public <T extends View> T findViewById(@IdRes int viewId) {
        if (getView() == null) {
            return null;
        }
        return getView().findViewById(viewId);
    }

    /**
     * 在UI线程中执行业务
     *
     * @param runnable 业务实现
     */
    public void runOnUiThread(Runnable runnable) {
        FragmentActivity activity = getActivity();
        if (activity != null) {
            activity.runOnUiThread(runnable);
        }
    }

    /**
     * 获取消息提示UIView
     */
    public UIView getUIView() {
        return mUIView;
    }

    public int getWidth() {
        if (getView() == null) {
            return 0;
        }
        return getView().getMeasuredWidth();
    }

    public int getHeight() {
        if (getView() == null) {
            return 0;
        }
        return getView().getMeasuredHeight();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onEventMainThread(EventData event) {
        this.onReceiveMessageEvent(event);
    }

    /**
     * 当接收到EventBus事件时会调用
     */
    protected void onReceiveMessageEvent(EventData event) {
    }

    /**
     * 当前fragment对于用户可见或不可见时回调
     */
    protected void onUserVisible(boolean isVisible) {
    }
}
